package com.zh.config.db

import android.annotation.SuppressLint
import android.content.ContentValues
import android.content.Context
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.util.Log
import java.io.File

class DbDownloadHelper : SQLiteOpenHelper, DownloadStorage {

    val DOWNLOAD_TABLE = "download"
    val DOWNLOAD_COLUMN_ID = "_id"
    val DOWNLOAD_COLUMN_URL = "url"
    val DOWNLOAD_COLUMN_NAME = "name"
    val DOWNLOAD_COLUMN_LOGO = "logo"
    val DOWNLOAD_COLUMN_FILE_PATH = "filePath"
    val DOWNLOAD_COLUMN_STATE = "state"
    val DOWNLOAD_COLUMN_TOTAL = "total"
    val DOWNLOAD_COLUMN_TIME = "time"
    val DOWNLOAD_ALL_COLUMNS = arrayOf(
        DOWNLOAD_COLUMN_ID,
        DOWNLOAD_COLUMN_URL,
        DOWNLOAD_COLUMN_NAME,
        DOWNLOAD_COLUMN_LOGO,
        DOWNLOAD_COLUMN_FILE_PATH,
        DOWNLOAD_COLUMN_STATE,
        DOWNLOAD_COLUMN_TOTAL,
        DOWNLOAD_COLUMN_TIME
    )
    val DOWNLOAD_CREATE_SQL = "CREATE TABLE " + DOWNLOAD_TABLE + " (" +
            DOWNLOAD_COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
            DOWNLOAD_COLUMN_URL + " TEXT NOT NULL," +
            DOWNLOAD_COLUMN_NAME + " TEXT," +
            DOWNLOAD_COLUMN_LOGO + " TEXT," +
            DOWNLOAD_COLUMN_FILE_PATH + " TEXT," +
            DOWNLOAD_COLUMN_STATE + " INTEGER," +
            DOWNLOAD_COLUMN_TOTAL + " INTEGER," +
            DOWNLOAD_COLUMN_TIME + " INTEGER NOT NULL" +
            ")"

    constructor(context: Context?) : super(context, "xy_download.db", null, 1)

    override fun onCreate(db: SQLiteDatabase?) {
        db?.execSQL(DOWNLOAD_CREATE_SQL)
    }

    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {

    }

    override fun put(url: String, sourceInfo: DownloadDao) {
        Log.i("db", sourceInfo.toString())
        val sourceInfoFromDb: DownloadDao? = getDownload(url)
        val exist = sourceInfoFromDb != null
        val contentValues = convert(sourceInfo)
        if (exist) {
            update(contentValues, sourceInfoFromDb!!.id)
        } else {
            writableDatabase.insert(DOWNLOAD_TABLE, null, contentValues)
        }
    }

    override fun getDownload(url: String): DownloadDao? {
        var cursor: Cursor? = null
        return try {
            cursor = readableDatabase.query(
                DOWNLOAD_TABLE,
                DOWNLOAD_ALL_COLUMNS,
                "$DOWNLOAD_COLUMN_URL=?",
                arrayOf(url),
                null,
                null,
                null
            )
            if (cursor == null || !cursor.moveToFirst()) null else convert(cursor)
        } catch (e: Exception) {
            e.printStackTrace()
            cursor?.close()
            null
        }
    }

    //是否存在这条数据
    fun hasDownload(url: String, time: Int): DownloadDao? {
        var cursor: Cursor? = null
        return try {
            cursor = readableDatabase.query(
                DOWNLOAD_TABLE,
                DOWNLOAD_ALL_COLUMNS,
                "$DOWNLOAD_COLUMN_URL=? AND $DOWNLOAD_COLUMN_TIME=?",
                arrayOf(url, time.toString()),
                null,
                null,
                null
            )
            if (cursor == null || !cursor.moveToFirst()) null else convert(cursor)
        } catch (e: Exception) {
            e.printStackTrace()
            cursor?.close()
            null
        }
    }

    override fun getAllDownload(): MutableList<DownloadDao>? {
        var cursor: Cursor? = null
        return try {
            cursor = readableDatabase.query(
                DOWNLOAD_TABLE, null, null, null, null, null, null
            )
            (if (cursor == null || !cursor.moveToFirst()) null else convertAll(cursor))
        } catch (e: Exception) {
            e.printStackTrace()
            cursor?.close()
            null
        }
    }

    override fun count(): Int {
        var cursor: Cursor? = null
        var count = 0
        try {
            cursor = writableDatabase.rawQuery("SELECT COUNT(*) FROM $DOWNLOAD_TABLE", null)
            if (cursor.moveToFirst()) {
                count = cursor.getLong(0).toInt()
            }
            cursor.close()
        } catch (e: Exception) {
            e.printStackTrace()
            cursor?.close()
        }
        return count
    }

    override fun remove(url: String, time: Int) {
        try {
            writableDatabase.delete(
                DOWNLOAD_TABLE,
                "$DOWNLOAD_COLUMN_URL=? AND $DOWNLOAD_COLUMN_TIME=?",
                arrayOf(url, time.toString())
            )
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    override fun removeAll() {
        try {
            writableDatabase.delete(DOWNLOAD_TABLE, "", null)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    override fun release() {
        close()
    }

    @SuppressLint("SuspiciousIndentation")
    private fun convertAll(cursor: Cursor): MutableList<DownloadDao> {
        val list: MutableList<DownloadDao> = ArrayList()
        if (cursor.moveToFirst()) {
            do {
                val dao = DownloadDao(
                    cursor.getInt(cursor.getColumnIndexOrThrow(DOWNLOAD_COLUMN_ID)),
                    cursor.getString(cursor.getColumnIndexOrThrow(DOWNLOAD_COLUMN_URL)),
                    cursor.getString(cursor.getColumnIndexOrThrow(DOWNLOAD_COLUMN_NAME)),
                    cursor.getString(cursor.getColumnIndexOrThrow(DOWNLOAD_COLUMN_LOGO)),
                    cursor.getString(cursor.getColumnIndexOrThrow(DOWNLOAD_COLUMN_FILE_PATH)),
                    cursor.getInt(cursor.getColumnIndexOrThrow(DOWNLOAD_COLUMN_STATE)),
                    cursor.getInt(cursor.getColumnIndexOrThrow(DOWNLOAD_COLUMN_TOTAL)),
                    cursor.getInt(cursor.getColumnIndexOrThrow(DOWNLOAD_COLUMN_TIME)),
                )
                if (dao.state == DownEnum.completed.state) {
                    val file = File(dao.filePath)
                    if (!file.exists()) {
                        val dao2 = DownloadDao(
                            dao.id, dao.url, dao.name, dao.logo,
                            file.absolutePath, DownEnum.delete.state, dao.total, dao.time
                        )
                        list.add(dao2)
                        val contentValues = convert(dao2)
                        update(contentValues, dao2.id)
                    } else {
                        list.add(dao)
                    }
                } else {
                    list.add(dao)
                }
            } while (cursor.moveToNext())
        }
        cursor.close()
        return list
    }

    private fun convert(sourceInfo: DownloadDao): ContentValues? {
        val values = ContentValues()
        values.put(DOWNLOAD_COLUMN_URL, sourceInfo.url)
        values.put(DOWNLOAD_COLUMN_NAME, sourceInfo.name)
        values.put(DOWNLOAD_COLUMN_LOGO, sourceInfo.logo)
        values.put(DOWNLOAD_COLUMN_FILE_PATH, sourceInfo.filePath)
        values.put(DOWNLOAD_COLUMN_STATE, sourceInfo.state)
        values.put(DOWNLOAD_COLUMN_TOTAL, sourceInfo.total)
        values.put(DOWNLOAD_COLUMN_TIME, sourceInfo.time)
        return values
    }

    private fun convert(cursor: Cursor): DownloadDao {
        val dao = DownloadDao(
            cursor.getInt(cursor.getColumnIndexOrThrow(DOWNLOAD_COLUMN_ID)),
            cursor.getString(cursor.getColumnIndexOrThrow(DOWNLOAD_COLUMN_URL)),
            cursor.getString(cursor.getColumnIndexOrThrow(DOWNLOAD_COLUMN_NAME)),
            cursor.getString(cursor.getColumnIndexOrThrow(DOWNLOAD_COLUMN_LOGO)),
            cursor.getString(cursor.getColumnIndexOrThrow(DOWNLOAD_COLUMN_FILE_PATH)),
            cursor.getInt(cursor.getColumnIndexOrThrow(DOWNLOAD_COLUMN_STATE)),
            cursor.getInt(cursor.getColumnIndexOrThrow(DOWNLOAD_COLUMN_TOTAL)),
            cursor.getInt(cursor.getColumnIndexOrThrow(DOWNLOAD_COLUMN_TIME)),
        )
        if (dao.state == DownEnum.completed.state) {
            val file = File(dao.filePath)
            return if (!file.exists()) {
                val dao2 = DownloadDao(
                    dao.id, dao.url, dao.name, dao.logo, file.absolutePath,
                    DownEnum.delete.state, dao.total, dao.time
                )
                val contentValues = convert(dao2)
                update(contentValues, dao2.id)
                cursor.close()
                dao2
            } else {
                cursor.close()
                dao
            }
        }
        cursor.close()
        return dao
    }

    private fun update(contentValues: ContentValues?, id: Int) {
        writableDatabase.update(
            DOWNLOAD_TABLE,
            contentValues,
            "$DOWNLOAD_COLUMN_ID=?",
            arrayOf(id.toString())
        )
    }
}